# TODO: Add comment
# 
# Author: rogb
###############################################################################

setClass("SwapRate",
		contains=c("FixPaymentFrequency","Term","Rate","SituationDate","EffectiveDate","MaturityDate","BasicInstrument","Exchange","DayCountConvention","Price")
)

# sw1 <- SwapRate(10,2.5,1,"CHF","Roger",Sys.Date(),"30/360","SWISSEXCHANGE")

SwapRate <- function(Term,Rate,FixPaymentFrequency,Currency,Name,SituationDate,DayCountConvention,Exchange){
	if(missing(SituationDate)){
		SituationDate <- Sys.Date()
	}
	if(missing(Exchange)){
		Exchange <- "DEFAULTEXCHANGE"
	}
	
	EffectiveDate <- getTradingDay(SituationDate + 2,Exchange=Exchange,Direction=1)
	if(Currency=="GBP"){
		EffectiveDate <- SituationDate
	}
	
	MaturityDate <- plusYear(EffectiveDate,Term)
	
	new("SwapRate",Term=Term,Rate=Rate,FixPaymentFrequency=FixPaymentFrequency,Currency=Currency,Name=Name,SituationDate=SituationDate,EffectiveDate=EffectiveDate,MaturityDate=MaturityDate,DayCountConvention=DayCountConvention,Exchange=Exchange)
}

setMethod("show","SwapRate",function(object){
			cat(object@Currency," ",object@Name," ",situationDate.character(object),"\n",sep="")
			cat("Term:      ",object@Term,"\n",sep="")
			cat("Frequency: ",object@FixPaymentFrequency,"\n",sep="")
			cat("Rate:      ",object@Rate,"\n",sep="")
		})

setMethod("generateCashFlows","SwapRate",function(object){
			EffectiveDate <- object@EffectiveDate
			MaturityDate <- object@MaturityDate
			officialInterestDates <- monthlyDateSequence(EffectiveDate,MaturityDate,object@FixPaymentFrequency,Direction=-1,overlapping=TRUE,keepEndOfMonth=TRUE)
			interestPaymentDates <- getTradingDay(officialInterestDates,Exchange=object@Exchange,Direction=1)
			n <- length(interestPaymentDates)
			CashFlow <- accruedInterest(object@Rate,object@DayCountConvention,object@FixPaymentFrequency,interestPaymentDates[1:(n-1)],interestPaymentDates[2:n],interestPaymentDates[2:n])
			CashFlow[n-1] <- CashFlow[n-1] + 100
			CashFlow <- c(-100,CashFlow)
			CashFlow(object@Currency,object@Name,interestPaymentDates,CashFlow)
		})

# DF <- DiscountFactor(Sys.Date(),"CHF","Swap Rate",Sys.Date()+(0:9)*500,1*0.9^(0:9))

setMethod("presentValue",signature=c("SwapRate","DiscountFactor"),function(object,arg1){
			presentValue(generateCashFlows(object),arg1)
		})

setMethod("presentValue",signature=c("SwapRate","ZeroRateCurve"),function(object,arg1){
			DF <- as.DiscountFactor(arg1)
			presentValue(generateCashFlows(object),DF)
		})

# Term <- 20
# FixPaymentFrequency <- 1
# Currency <- "CHF"
# SituationDate <- Sys.Date()
# DayCountConvention <- "30/360"
# Exchange <- "SWISSEXCHANGE"
# Name <- "Swap Rate"

estimateParSwapRate <- function(Term,FixPaymentFrequency,Currency,Name,SituationDate,DayCountConvention,Exchange,DF){
	f <- function(Rate){
		# Rate <- 3
		0 - presentValue(SwapRate(Term,Rate,FixPaymentFrequency,Currency,Name,SituationDate,DayCountConvention,Exchange),DF)
	}
	Rate <- uniroot(f,c(0,100))$root
	SwapRate(Term,Rate,FixPaymentFrequency,Currency,Name,SituationDate,DayCountConvention,Exchange)
}

# object <- sw6
setMethod("estimateIRR",signature=c("SwapRate"),function(object){
			PV <- price(object)
			CF <- generateCashFlows(object)
			n <- dim(CF)[1]
			MaturityDate <- getDate(CF)[n]
			Currency <- currency(object)
			SituationDate <- situationDate(object)
			Date <- getDate(CF)
			f <- function(Rate){
				ZR <- ZeroRateCurve(SituationDate,Currency,object@Name,c(SituationDate,Date),rep(Rate,n+1))
				PV - presentValue(object,ZR)
			}
			Rate <- uniroot(f,c(0,100),maxiter = 100000)$root
			# ZeroRateCurve(SituationDate,Currency,object@Name,c(SituationDate,Date),rep(Rate,n+1))
			Rate
		})

#  sw2 <- estimateParSwapRate(Term,FixPaymentFrequency,Currency,Name,SituationDate,DayCountConvention,Exchange,DF)
# presentValue(sw2,DF)

#year <- as.numeric(format(Sys.Date(),"%Y"))
#month <- as.numeric(format(Sys.Date(),"%m"))
#day <- as.numeric(format(Sys.Date(),"%d"))
#years <- year + 1:10
#Date <- as.Date(paste(years,month,day,sep="-"))
#Rate <- rep(object@Rate,object@Term)
#sw1 <- SwapRate(20,4.2,2,"CHF",Sys.Date(),"ISDA:Act/Act","SWISSEXCHANGE")
#object <- SwapRate(20,5.3,2,"CHF",Sys.Date(),"ISDA:Act/Act","SWISSEXCHANGE")
#sw2 <- SwapRate(5,2.7,2,"CHF",Sys.Date()+10,"30/360","SWISSEXCHANGE")
#sw2 <- SwapRate(10,4.8,2,"CHF",Sys.Date()+10,"30/360","SWISSEXCHANGE")
#cf1 <- generateCashFlows(sw1)
#cf2 <- generateCashFlows(sw2)
#plot(cf1)
